<template>
    <view class="exam-radio-group" :class="bemClass">
        <slot></slot>
    </view>
</template>

<script>
export default {
    name: 'exam-radio-group',
    props: {
        // 是否禁用所有单选框
        disabled: {
            type: Boolean,
            default: false,
        },
        // 匹配某一个radio组件，如果某个radio的name值等于此值，那么这个radio就被会选中
        value: {
            type: [String, Number],
            default: '',
        },
        // 选中状态下的颜色
        activeColor: {
            type: String,
            default: '#2979ff',
        },
        // 禁用状态下的颜色
        disabledColor: {
            type: String,
            default: '#2979ff',
        },
        // 组件的整体大小
        size: {
            type: [String, Number],
            default: 44,
        },
        // 是否禁止点击提示语选中复选框
        labelDisabled: {
            type: Boolean,
            default: false,
        },
        // 图标的大小，单位rpx
        iconSize: {
            type: [String, Number],
            default: 20,
        },
        // 布局方式，row-横向，column-纵向
        placement: {
            type: String,
            default: 'row',
        },
    },
    created() {
        // 如果将children定义在data中，在微信小程序会造成循环引用而报错
        this.children = []
    },
    watch: {
        // 当父组件需要子组件需要共享的参数发生了变化，手动通知子组件
        parentData() {
            if (this.children.length) {
                this.children.map((child) => {
                    // 判断子组件(edu-radio)如果有updateParentData方法的话，就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                    typeof child.updateParentData == 'function' && child.updateParentData()
                })
            }
        },
    },
    computed: {
        parentData() {
            return [
                this.value,
                this.disabled,
                this.activeColor,
                this.disabledColor,
                this.size,
                this.labelDisabled,
                this.iconSize,
                this.placement,
            ]
        },
        bemClass() {
            return this.bem('radio-group', ['placement'])
        },
        /**
         * 生成bem规则类名
         * 由于微信小程序，H5，nvue之间绑定class的差异，无法通过:class="[bem()]"的形式进行同用
         * 故采用如下折中做法，最后返回的是数组（一般平台）或字符串（支付宝和字节跳动平台），类似['a', 'b', 'c']或'a b c'的形式
         * @param {String} name 组件名称
         * @param {Array} fixed 一直会存在的类名
         * @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名
         * @returns {Array|string}
         */
        bem() {
            return function (name, fixed, change) {
                // 类名前缀
                const prefix = `exam-${name}--`
                const classes = {}
                if (fixed) {
                    fixed.map((item) => {
                        // 这里的类名，会一直存在
                        classes[prefix + this[item]] = true
                    })
                }

                if (change) {
                    change.map((item) => {
                        // 这里的类名，会根据this[item]的值为true或者false，而进行添加或者移除某一个类
                        this[item]
                            ? (classes[prefix + item] = this[item])
                            : delete classes[prefix + item]
                    })
                }
                return Object.keys(classes)
            }
        },
    },
    watch: {
        // 当父组件需要子组件需要共享的参数发生了变化，手动通知子组件
        parentData() {
            if (this.children.length) {
                this.children.map((child) => {
                    // 判断子组件(u-radio)如果有init方法的话，就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
                    typeof child.init === 'function' && child.init()
                })
            }
        },
    },
    created() {
        this.children = []
    },
    methods: {
        // 将其他的radio设置为未选中的状态
        unCheckedOther(childInstance) {
            this.children.map((child) => {
                // 所有子radio中，被操作组件实例的checked的值无需修改
                if (childInstance !== child) {
                    child.checked = false
                }
            })
            const { name } = childInstance
            // 发出事件
            this.$emit('change', name)
            // 修改通过v-model绑定的值
            this.$emit('input', name)
        },
    },
}
</script>

<style lang="scss" scoped>
.exam-radio-group {
    display: flex;
    &--row {
        flex-direction: row;
        flex-wrap: wrap;
    }

    &--column {
        flex-direction: column;
    }
}
</style>
